/*
 * Copyright (c) 2023 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#ifndef BUS_I2C_H
#define BUS_I2C_H

#include "internal/bus/bus_base/bus.h"
#include "internal/hasdef.h"
#include <mc/engine.h>
#include <memory>
#include <string>
#include <string_view>

#include "drivers/i2c.h"

constexpr uint32_t MULTIIO_DEFAULT      = 255;
constexpr uint8_t  MAX_OFFSET_WIDTH     = 4;
constexpr uint32_t MAX_WRITE_LEN        = 1100;
constexpr uint32_t DEFAULT_TIMEOUT_MS   = 100;
constexpr uint32_t DEFAULT_SPEED        = 100;
constexpr uint8_t  DEFAULT_MODE         = 0;
constexpr uint8_t  DEFAULT_SLAVE_ADDR   = 0;
constexpr bool     DEFAULT_USE_SMBUS    = false;
constexpr uint32_t I2C_EXTEND_READ_MODE = 0xffffffff;

namespace dev {

class bus_i2c : public bus_base {
public:
    bool init(mc::mutable_dict& csr_object);

    std::unique_ptr<DRIVER_I2C::I2c> m_i2c_drv;

    std::string m_tx_buffer; // 发送缓冲区

    std::string_view format_tx_buf(const ACCESS_DATA_S& data);
    uint32_t         get_i2c_speed(uint32_t speed);

    // 实现虚函数
    uint32_t read(ACCESS_DATA_S& input) override;
    uint32_t write(ACCESS_DATA_S& input) override;
    uint32_t normal_read(ACCESS_DATA_S& data);
    uint32_t extend_read(ACCESS_DATA_S& data);
    uint8_t  get_id() override;
    void     bus_lock() override;
    void     bus_unlock() override;

private:
    uint8_t  m_id;
    uint32_t m_speed      = DEFAULT_SPEED;
    uint8_t  m_mode       = DEFAULT_MODE;
    uint8_t  m_slave_addr = DEFAULT_SLAVE_ADDR;
    bool     m_use_smbus  = DEFAULT_USE_SMBUS;
};

} // namespace dev

#endif // BUS_I2C_H